<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    /* 整个放大镜模块固定定位 */
    #box {
      position: relative;
      width: 300px;
      margin: 200px 0 0 200px;
    }

    /* 原图区域宽度100% */
    #box #one {
      width: 100%;
    }

    /* 图片展示区域默认隐藏 、固定定位、宽度高度都为100%，溢出隐藏*/
    #box #tow {
      display: none;
      position: absolute;
      top: 0;
      left: 105%;
      width: 100%;
      height: 100%;
      border: 5px solid #ccc;
      overflow: hidden;
    }

    /* 展示区域内部图片宽度200%，高度自适应 */
    #box #tow img {
      width: 200%;
    }

    /* 放大镜默认隐藏，固定定位，颜色特别 */
    #box #me {
      display: none;
      position: absolute;
      width: 100px;
      height: 100px;
      top: 0;
      left: 0;
      background-color: rgba(255, 155, 0, 0.5);

    }
  </style>
</head>

<body>
  <!-- 放大镜模块 -->
  <div id="box">
    <!-- //图片本体 -->
    <img id="one" src="./1.jpg" alt="">
    <!-- 放大镜 -->
    <span id="me"></span>
    <!-- 右侧展示区域 -->
    <span id="tow">
      <!-- 展示图片 -->
      <img src="./1.jpg" alt="">
    </span>

  </div>

  <script>
    // 把代码放到window.onload中，这个运行原理为：
    //鼠标移上原图片放大镜和右侧展示区域显示（默认隐藏），当鼠标在图片内移动时，放大镜跟着鼠标进行移动，但永远不会超出原图片四个边，同时右侧展示区域由于图片要大于展示区域面积，所以只能展示出图片的一部分，我们通过对应左侧图片和右侧图片的对应关系来同步更改右侧展示区域的scrollLeft和scrollTop属性，实现运动效果
    window.onload = function () {
      //获取元素
      var box = document.getElementById('box'),
        one = document.getElementById('one'),
        tow = document.getElementById('tow'),
        me = document.getElementById('me'),
        //获取放大镜定位top和left最大值，保证放大镜永远不会超出右边和下边
        //left = 元素宽度-放大镜宽度
        maxLeft = one.offsetWidth - 100,
        //top = 元素高度-放大镜高度
        maxTop = one.offsetHeight - 100;

      //整体盒子添加鼠标移上事件：显示放大镜和右侧展示区域
      box.onmouseover = function () {
        tow.style.display = 'block';
        me.style.display = 'block';
      }

      //整体盒子添加鼠标移出事件：隐藏放大镜和右侧展示区域
      box.onmouseout = function () {
        tow.style.display = 'none';
        me.style.display = 'none';
      }

      //整体盒子添加鼠标移动事件
      box.onmousemove = function (e) {
        //兼容写法
        var e = e || window.event,
          //创建两个信号量，分别代表放大镜的left定位和left定位
          nowLeft = 0,
          nowTop = 0

        //实时判断鼠标位置，并根据鼠标位置推算放大镜顶点位置（left和top）
        //如果计算出的顶点left位置<0，或者大于maxLeft（最大left值）强制把位置拉到0或者maxLeft（把0或者maxLeft赋值给nowLeft），因为放大镜绝对不能超出图片
        if (e.pageX - box.offsetLeft - 50 < 0) {
          nowLeft = 0;
        } else if (e.pageX - box.offsetLeft - 50 > maxLeft) {
          nowLeft = maxLeft;
        } else {
          //如果计算出的left值处于最小值0和最大值maxLeft之间，则将计算出的值赋值给nowLeft
          nowLeft = e.pageX - box.offsetLeft - 50
        }
        //这里是计算top值，原理同上
        if (e.pageY - box.offsetTop - 50 < 0) {
          nowTop = 0;
        } else if (e.pageY - box.offsetTop - 50 > maxTop) {
          nowTop = maxTop;
        } else {
          nowTop = e.pageY - box.offsetTop - 50;
        }

        //将计算后得到的nowLeft和nowTop加上px赋值给放大镜（me），修改定位位置
        me.style.left = nowLeft + 'px';
        me.style.top = nowTop + 'px';

        //由于右侧展示区域的长和宽等于左侧原图的两倍，所以我们可以简单粗暴的直接设置右侧展示区的scroll系列属性
        tow.scrollLeft = nowLeft * 2;
        tow.scrollTop = nowTop * 2;
      }
    }
  </script>
</body>

</html>